<template>
    <view class="content">
        <button @click="initBluetooth">初始化蓝牙</button>
        <button @click="startBluetoothDevicesDiscovery">开启搜索蓝牙</button>
        <button @click="stopBluetoothDevicesDiscovery">关闭搜索蓝牙</button>
        <button @click="getBluetoothDevices">获取蓝牙设备1</button>
        <button @click="createBLEConnection">连接蓝牙设备</button>
        <button @click="closeBLEConnection">断开连接蓝牙设备</button>

        <button @click="getBLEDeviceServices">获取蓝牙设备服务</button>
        <button @click="getBLEDeviceCharacteristics">获取蓝牙设备特征</button>
        <button @click="notifyBLECharacteristicValueChange">订阅蓝牙设备特征</button>
        <button @click="onBLECharacteristicValueChange">监听蓝牙设备特征变化</button>
        <button @click="offBLECharacteristicValueChange">移除监听蓝牙设备特征变化</button>
        <button @click="writeBLECharacteristicValue">写入蓝牙设备特征</button>
        <button @click="createArrayBuffer">生成ArrayBuffer</button>
    </view>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';

// 蓝牙测试
const bluetoothInfo = ref({});
const bluetoothServices = ref([]);
const bluetoothCharacteristics = ref([]);
const initBluetooth = () => {
    console.log('initBluetooth12');
    // 初始化蓝牙
    uni.openBluetoothAdapter({
        success: (res) => {
            console.log('openBluetoothAdapter success', res);
        },
        fail: (err) => {
            console.log('openBluetoothAdapter fail', err);
        },
    });
};

const startBluetoothDevicesDiscovery = () => {
    uni.startBluetoothDevicesDiscovery({
        services: ['0000FFE0'],
        success(res) {
            console.log('开始搜索蓝牙：', res);
        }
    })
}

const stopBluetoothDevicesDiscovery = () => {
    uni.stopBluetoothDevicesDiscovery({
        success(res) {
            console.log('停止搜索蓝牙：', res);
        }
    })
}

const getBluetoothDevices = () => {
    uni.getBluetoothDevices({
        success(res) {
            bluetoothInfo.value = res?.devices[1] || res?.devices[0];
            console.log('获取蓝牙设备：', res.devices, res.devices?.map((item: any) => item.deviceId));
        }
    })
}

// 连接蓝牙设备
const createBLEConnection = () => {
    uni.createBLEConnection({
        deviceId: bluetoothInfo.value.deviceId,
        success(res) {
            console.log('连接蓝牙设备：', res);
        }
    })
}

// 断开蓝牙
const closeBLEConnection = () => {
    uni.closeBLEConnection({
        deviceId: bluetoothInfo.value.deviceId,
        success(res) {
            console.log('蓝牙断开成功：', res)
        }
    })
}

const getBLEDeviceServices = () => {
    console.log('获取蓝牙设备服务：', bluetoothInfo.value.deviceId);
    uni.getBLEDeviceServices({
        // 这里的 deviceId 需要已经通过 wx.createBLEConnection 与对应设备建立连接
        deviceId: bluetoothInfo.value.deviceId,
        success(res) {
            bluetoothServices.value = res.services;
            console.log('device services:', res.services)
        },
        fail(res) {
            console.log('device services fail:', res)
        }
    })
}

const getBLEDeviceCharacteristics = () => {
    uni.getBLEDeviceCharacteristics({
        deviceId: bluetoothInfo.value.deviceId,
        serviceId: bluetoothServices.value[2].uuid,
        success(res) {
            bluetoothCharacteristics.value = res.characteristics;
            console.log('获取蓝牙设备特征：', res);
        }
    })
}

const notifyBLECharacteristicValueChange = () => {
    const param = {
        // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
        deviceId: bluetoothInfo.value.deviceId,
        // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
        serviceId: bluetoothServices.value[2].uuid,
        // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
        characteristicId: bluetoothCharacteristics.value[1].uuid,
    }
    console.log('监听蓝牙：', param)
    uni.notifyBLECharacteristicValueChange({
        state: true, // 启用 notify 功能
        ...param,
        success(res) {
            console.log('notifyBLECharacteristicValueChange success', res.errMsg)
        },
        fail(res) {
            console.log('notifyBLECharacteristicValueChange fail', res.errMsg)
        }
    })
}

const onBLECharacteristicValueChange = () => {
    function ab2hex(buffer) {
        let hexArr = Array.prototype.map.call(
            new Uint8Array(buffer),
            function (bit) {
                return ('00' + bit.toString(16)).slice(-2)
            }
        )
        return hexArr.join('');
    }
    uni.onBLECharacteristicValueChange(function (res) {
        console.log(`characteristic ${res.characteristicId} has changed, now is：`, res.value);
        console.log(ab2hex(res.value))
    })
}

const offBLECharacteristicValueChange = () => {
    uni.offBLECharacteristicValueChange(function (res) {
        console.log('stop notifyBLECharacteristicValueChange success', res.errMsg)
    })
}

const setArrayBuffer = (buffer) => {
    let dataView = new DataView(buffer);
    let arr = new Array(buffer.byteLength);
    for (let i = 0; i < buffer.byteLength; i++) {
        arr[i] = dataView.getUint8(i);
    }
    return arr;
}

const createArrayBuffer = () => {
    // 1. 得到输入的数据字符串
    let str = '4154542B434845434B0D0A';
    // 2. 创建一个与十六进制字符串长度一半相等的 Uint8Array
    let uint8 = new Uint8Array(str.length / 2);
    // 3. 遍历十六进制字符串，每两个字符一组转换为十进制数值
    for (let i = 0; i < str.length; i += 2) {
        uint8[i / 2] = parseInt(str.substr(i, 2), 16);
    }
    console.log('createArrayBuffer', uint8, uint8.buffer);
    return uint8.buffer;
}

// 写入蓝牙设备特征
const writeBLECharacteristicValue = () => {
    // 向蓝牙设备发送一个0x00的16进制数据
    // let buffer = new ArrayBuffer('ATT+CHECK\r\n')
    // let dataView = new DataView(buffer)
    // dataView.setUint8(0, 0)

    uni.writeBLECharacteristicValue({
        // 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
        deviceId: bluetoothInfo.value.deviceId,
        // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
        serviceId: bluetoothServices.value[2].uuid,
        // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
        characteristicId: bluetoothCharacteristics.value[0].uuid,
        // 这里的value是ArrayBuffer类型
        value: createArrayBuffer(),
        success(res) {
            console.log('writeBLECharacteristicValue success', res.errMsg)
        },
        fail(res) {
            console.log('writeBLECharacteristicValue fail', res.errMsg)
        }
    })
}
</script>

<style>
.content {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.logo {
    height: 200rpx;
    width: 200rpx;
    margin-top: 200rpx;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 50rpx;
}

.text-area {
    display: flex;
    justify-content: center;
}

.title {
    font-size: 36rpx;
    color: #8f8f94;
}
</style>